﻿using System;
using System.Globalization;

namespace Jeneva.Impl
{
    /// <summary>
    /// Defines set of standard .net types parsers
    /// </summary>
    public static class StandardParsers
    {
        internal static readonly IParser STRING_PARSER = new StringParser();
        internal static readonly IParser LONG_PARSER = new LongParser();
        internal static readonly IParser ULONG_PARSER = new ULongParser();
        internal static readonly IParser INT_PARSER = new IntParser();
        internal static readonly IParser UINT_PARSER = new UIntParser();
        internal static readonly IParser SHORT_PARSER = new ShortParser();
        internal static readonly IParser USHORT_PARSER = new UShortParser();
        internal static readonly IParser BYTE_PARSER = new ByteParser();
        internal static readonly IParser SBYTE_PARSER = new SByteParser();
        internal static readonly IParser DOUBLE_PARSER = new DoubleParser();
        internal static readonly IParser DECIMAL_PARSER = new DecimalParser();
        internal static readonly IParser FLOAT_PARSER = new FloatParser();
        internal static readonly IParser BOOL_PARSER = new BoolParser();
        internal static readonly IParser CHAR_PARSER = new CharParser();
        internal static readonly IParser ENUM_PARSER = new EnumParser();
        internal static readonly IParser ENUM_NULLABLE_PARSER = new EnumNullableParser();
        internal static readonly IParser DATETIME_PARSER = new DateTimeParser();
        internal static readonly IParser GUID_PARSER = new GuidParser();

        private class StringParser : IParser
        {
            public object ParseTextValue(Type type, string text)
            {
                return text;
            }
        }

        private class LongParser : IParser
        {
            public object ParseTextValue(Type type, string text)
            {
                return long.Parse(text);
            }
        }

        private class ULongParser : IParser
        {
            public object ParseTextValue(Type type, string text)
            {
                return ulong.Parse(text);
            }
        }

        private class IntParser : IParser
        {
            public object ParseTextValue(Type type, string text)
            {
                return int.Parse(text);
            }
        }

        private class UIntParser : IParser
        {
            public object ParseTextValue(Type type, string text)
            {
                return uint.Parse(text);
            }
        }

        private class ShortParser : IParser
        {
            public object ParseTextValue(Type type, string text)
            {
                return short.Parse(text);
            }
        }

        private class UShortParser : IParser
        {
            public object ParseTextValue(Type type, string text)
            {
                return ushort.Parse(text);
            }
        }

        private class ByteParser : IParser
        {
            public object ParseTextValue(Type type, string text)
            {
                return byte.Parse(text);
            }
        }

        private class SByteParser : IParser
        {
            public object ParseTextValue(Type type, string text)
            {
                return sbyte.Parse(text);
            }
        }

        private class DoubleParser : IParser
        {
            public object ParseTextValue(Type type, string text)
            {
                return double.Parse(text, CultureInfo.InvariantCulture);
            }
        }

        private class DecimalParser : IParser
        {
            public object ParseTextValue(Type type, string text)
            {
                return decimal.Parse(text, CultureInfo.InvariantCulture);
            }
        }

        private class FloatParser : IParser
        {
            public object ParseTextValue(Type type, string text)
            {
                return float.Parse(text, CultureInfo.InvariantCulture);
            }
        }

        private class BoolParser : IParser
        {
            public object ParseTextValue(Type type, string text)
            {
                return bool.Parse(text);
            }
        }

        private class CharParser : IParser
        {
            public object ParseTextValue(Type type, string text)
            {
                return text[0];
            }
        }

        private class EnumParser : IParser
        {
            public object ParseTextValue(Type type, string text)
            {
                return Enum.Parse(type, text);
            }
        }

        private class EnumNullableParser : IParser
        {
            public object ParseTextValue(Type type, string text)
            {
                if (string.IsNullOrEmpty(text))
                {
                    return null;
                }
                else
                {
                    return Enum.Parse(type.GenericTypeArguments[0], text);
                }
            }
        }

        private class DateTimeParser : IParser
        {
            public object ParseTextValue(Type type, string text)
            {
                return DateTime.Parse(text, CultureInfo.InvariantCulture.DateTimeFormat, DateTimeStyles.AssumeUniversal);
            }
        }

        private class GuidParser : IParser
        {
            public object ParseTextValue(Type type, string text)
            {
                return Guid.Parse(text);
            }
        }
    }
}